/*
 * @Author: Zhang Kai
 * @Date: 2021-11-11 20:46:54
 * @LastEditors: mayijun
 * @LastEditTime: 2022-08-05 16:26:08
 * @FilePath: /metricsx-standard-ui/src/components/Arithmetic/components/SelectIndex.tsx
 */
//衍生指标选择运算逻辑，快速的创建一个不被管理的指标，不再指标管理列表展示，只用于计算
import API from '@/services';
import { ElMessage } from 'element-plus/lib/index';
import {
  computed,
  defineComponent,
  onMounted,
  PropType,
  reactive,
  ref,
  watch
} from 'vue';
import '../style/selectIndex.scss';
import ArithmeticDetail from './ArithmeticDetail';
import ModifierCascader from '@/components/ModifierCascader';
import _ from 'lodash';
import qs from 'qs';
import { useRoute } from 'vue-router';
import { store } from '@/store';
const SelectIndex = defineComponent({
  name: 'SelectIndex',
  props: {
    dialogVisible: {
      type: Boolean,
      default: false
    },
    //是否只保留指标选择
    isOnlyIndex: {
      type: Boolean,
      default: false
    },
    /* 指标列表API类型 */
    metricsType: {
      type: String,
      default: 'DERIVED'
    },
    //当前指标id
    indexItem: {
      type: Object,
      default: () => { }
    },
    /* 当前主题id */
    subjectId: {
      type: String,
      default: ''
    },
    /* 是否需要左侧主题 */
    isSubject: {
      type: Boolean,
      default: true
    },
    /* 定制指标列表 需要配合isSubject使用 */
    list: {
      type: Array,
      default: () => []
    },
    /* 是否需要详情 */
    isDetail: {
      type: Boolean,
      default: true
    },
    /* 是否需要远程搜索 */
    isRemote: {
      type: Boolean,
      default: true
    },
    /* 指标跳转地址 */
    skipUrl: {
      type: String,
      default: `${process.env.VUE_APP_PUBLICPATH === '/'
        ? ''
        : process.env.VUE_APP_PUBLICPATH
        }/#/index-manage/indexManage?modal=1`
    },
    /* 是否需要新建指标跳转 */
    isSkip: {
      type: Boolean,
      default: false
    },
    /* 指标类型 */
    subType: {
      type: Number,
      default: 1,
    },
    //可选维度id
    chosenDimensionIds: {
      type: Array as PropType<any[]>,
      default: () => []
    },
    //可选维度id
    chosenMetricsIds: {
      type: Array as PropType<any[]>,
      default: () => []
    },
    isMetricsFavorite: {
      type: Boolean,
      default: false
    },
    isConfig: {
      type: Boolean,
      default: true
    },
  },
  emits: ['indexChange', 'update:dialogVisible', 'optionChange'],
  setup: (props, { slots, attrs, emit }) => {
    const subjectDeepList: any = ref([]);

    const cascaderModel = ref();

    const currentIndex = ref();

    const indexList = ref();

    /* 修饰词list */
    const modifierList: any = ref([]);

    const route = useRoute();

    const state = reactive({
      currentItem: {} as any, //当前指标对象
      pageNum: 1,
      pageSize: 10,
      isLastPage: false, //是否最后一页
      isAddEvent: false, //判断是否已经添加监听
      keyword: '', //指标搜索关键词
      isDisableGroupName: true,
      groupName: "",
      modifierIds: [] as any[],
      selectModifierList: [] as any[],
      loading: false,
    });

    let dialogVisibles = computed({
      get: () => props.dialogVisible,
      set: (v) => emit('update:dialogVisible', v)
    });

    const formatDetail = (v: any) => {
      return [
        {
          label: '基本信息',
          value: [
            {
              name: '英文名称:',
              value: v?.enName
            },
            {
              name: '主题:',
              value: v?.subjectLayers
                ?.map((v: any) => v?.subjectName)
                .join(' | ')
            },
            {
              name: '业务负责人:',
              value: v?.businessOwner
            },
            {
              name: '研发负责人:',
              value: v?.techOwner
            },
          ]
        },
        {
          label: '业务含义',
          value: v?.derivedBusinessMeaning || v?.businessMeaning
        },
        {
          label: '备注',
          value: v.description
        }
      ];
    };

    /* 主题 */
    const getSubjectDeepList = async () => {
      try {
        const { code, data } = await API.subject.getSubjectsSimpleList();
        if (code === 200 && Array.isArray(data)) {
          subjectDeepList.value = data;
        }
      } catch (error) {
        console.log(error);
      }
    };

    /* 指标列表 */
    const getArithmeticList = async () => {
      if (!props?.isRemote) return;
      try {
        let resp: any = {};
        if (props.isOnlyIndex && props.isConfig) {
          console.log(route.name, '此时路由名')
          if (route.name === 'applicationFetchScene') {
            console.log('走场景取数专有的接口')
            resp = await API.sceneTaskManager.getHintMetrics({
              metricsContent: state.keyword,
              sceneId: store.state.metricsapplication.scenesId
            });
          } else {
            resp = await API.taskManagerV1.getHintMetrics({
              metricsContent: state.keyword,
              chosenDimensionIds: props.chosenDimensionIds,
              chosenMetricsIds: props.chosenMetricsIds,
              isMetricsFavorite: props.isMetricsFavorite
            });

          }
          if (resp.code === 200 && Array.isArray(resp.data)) {
            const indexDataList = resp.data.map((v: any) => ({
              ...v,
              label: v.cnName
            }));
            indexList.value = indexDataList;
          }
        } else {
          resp = await API.metrics.getMetricsHintSimpleList({
            pageNum: state.pageNum,
            pageSize: state.pageSize,
            subjectId: cascaderModel.value,
            content: state.keyword,
            reviewStatusCode: props.isOnlyIndex ? 0 : 5,
            types: [1, 2, 3] as any[]
          });
          if (resp.code === 200 && Array.isArray(resp.data.list)) {
            const indexDataList = resp.data.list.map((v: any) => ({
              ...v,
              label: v.cnName
            }));
            if (resp.data.pageNum > 1) {
              indexList.value = [...indexList.value, ...indexDataList];
            } else {
              indexList.value = indexDataList;
            }
            state.pageNum = resp.data.pageNum;
            state.isLastPage = resp.data.isLastPage;
          }
        }

      } catch (error) {
        console.log(error);
      }
    };

    //给select框加滚动监测
    const setLoadMore = (cur: Document) => {
      //获得popper元素
      const popperElement = document.getElementsByClassName('derive-popper')[0];

      if (popperElement) {
        //获取下拉框div元素
        const loadSelectElement = popperElement.getElementsByClassName(
          'el-select-dropdown__wrap'
        )[0];

        const scrollLoadData = () => {
          // 当滚动条高度等于卷入高度+可视高度时，说明到达底部，scrollHeight :滚动条高度，scrollTop ：已卷入不可见的滚动条高度，clientHeight：可见的滚动条高度。
          const scrollDistance =
            loadSelectElement.scrollHeight -
            loadSelectElement.scrollTop -
            loadSelectElement.clientHeight;
          // 非搜索,不是最后一页
          if (scrollDistance <= 0 && !state.isLastPage) {
            //页码依次加1
            state.pageNum += 1;
            //查询指标
            getArithmeticList();
          }
        };
        //增加防抖
        if (!state.isAddEvent) {
          state.isAddEvent = true;
          console.log(loadSelectElement);
          loadSelectElement?.addEventListener(
            'scroll',
            _.throttle(scrollLoadData, 500)
          );
        }

        //如果已加载全部数据，取消监听
        if (state.isLastPage) {
          state.isAddEvent = false;
          loadSelectElement?.removeEventListener('scroll', scrollLoadData);
        }
      }

    };

    //获取修饰词
    const getModifierList = async (name?: string) => {
      try {
        const { code, data } = await API.modifier.getModifierNameHint({
          cnName: name
        });
        if (code === 200 && Array.isArray(data)) {
          //处理修饰词树形结构
          let array: any[] = [];
          data.map((item) => {
            let child = {
              label: item.cnName,
              value: item.id,
              enName: item.enName,
              businessMeaning: item.businessMeaning,
              type: item.type,
            }
            let hasNode = array.find(obj => obj.value == item.type);
            if (hasNode) {
              hasNode.children.push(child);
            } else {
              let parent = {
                label: item.typeName,
                value: item.type,
                children: [child]
              }
              array.push(parent);
            }
          });
          modifierList.value = array;
        }
      } catch (error) {
        console.log(error);
      }
    }

    //修饰词格式处理
    const modifierIdsFormat = (data: any) => {
      if (data.length == 0) {
        return "";
      }
      let ids = data.map((obj: any) => {
        return obj[1];
      });
      return ids.join(";");
    }

    //拼接数据，指标名称、业务含义
    const splitData = () => {
      let timeModifierCnName = "";
      let businessModifierCnName = "";
      let atomCnName = state.currentItem.cnName || "";
      //时间修饰词
      let timeModifier = state.selectModifierList.find(item => item.type == 1);
      if (timeModifier) {
        timeModifierCnName = timeModifier.label;
      }
      //业务修饰词
      state.selectModifierList.map(item => {
        if (item.type == 2) {
          businessModifierCnName += item.label;
        }
      });
      //拼接数据   时间修饰词（0-1）+ 业务修饰词（0-多个）+ 原子指标
      state.groupName = timeModifierCnName + businessModifierCnName + atomCnName;
    }

    watch(
      () => props.dialogVisible,
      () => {
        //打开时才执行
        if (props.dialogVisible) {
          //currentIndex.value = Number(props?.indexItem?.id) || ''; //反显
          //cascaderModel.value = props?.subjectId || ''; //分类
          //state.keyword = props?.indexItem?.label; //关键词搜索
          //查询指标
          getArithmeticList();
          getSubjectDeepList();
          getModifierList();
        }
      }
    );

    return () => {
      const { isSubject, isDetail, skipUrl, isSkip, isRemote, isOnlyIndex } = props;
      return (
        <el-dialog
          append-to-body
          customClass="SelectIndex"
          v-model={dialogVisibles.value}
          title="添加指标"
          onClose={() => {
            dialogVisibles.value = false;
            cascaderModel.value = '';//主题
            currentIndex.value = '';//指标
            state.modifierIds = [];//修饰词
            state.selectModifierList = [];
            state.keyword = "";//清空搜索
            state.groupName = "";//组合名称
            state.currentItem = {};
            state.pageNum = 1;
            state.pageSize = 10;
          }}
          v-slots={{
            footer: () => (
              <>
                <el-button
                  onClick={() => {
                    dialogVisibles.value = false;
                  }}
                >
                  取消
                </el-button>
                <el-button
                  loading={state.loading}
                  onClick={async () => {
                    if (!currentIndex.value) {
                      ElMessage.warning('请选择指标');
                      return;
                    }
                    let obj = state.currentItem;
                    if (props.isOnlyIndex) {
                      emit('indexChange', obj);
                      dialogVisibles.value = false;
                    } else {
                      if (!state.groupName) {
                        ElMessage.warning('请输入组合名称');
                        return;
                      }
                      obj.label = state.groupName;
                      //创建一个4类型的指标，用于衍生指标计算
                      let params = {
                        typeCode: 4 as any,
                        dependMetricsId: obj.id,
                        modifierIds: "",
                        cnName: state.groupName,
                      }
                      //修饰词拼接
                      if (state.modifierIds.length > 0) {
                        params.modifierIds = modifierIdsFormat(state.modifierIds);
                      }
                      state.loading = true;
                      const { code, data }: any = await API.metrics.postMetrics({ ...params });
                      if (code == 200 && data) {
                        obj.id = data.id;
                        obj.businessMeaning = data.fixedBusinessMeaning;
                        obj.type = data.metricsType;
                        emit('indexChange', obj);
                        dialogVisibles.value = false;
                        state.loading = false;
                      } else {
                        state.loading = false;
                        ElMessage.error('添加指标失败');
                      }
                    }

                  }}
                  type="primary"
                >
                  确定
                </el-button>
              </>
            )
          }}
        >
          <div class="SelectIndex-content">
            <div class="select-label is-not">选择指标：</div>
            <div class={['select',isSubject?'is-subject':'']}>
              {/* 主题 */}
              {isSubject ? (
                <el-cascader
                  v-model={cascaderModel.value}
                  popperClass="ArithmeticSelect-popper"
                  options={subjectDeepList.value}
                  clearable
                  size="large"
                  show-all-levels={false}
                  onChange={(v: any) => {
                    cascaderModel.value = v?.length && v[v?.length - 1];
                    currentIndex.value = '';
                    state.keyword = '';
                    state.pageNum = 1;
                    getArithmeticList();
                  }}
                />
              ) : undefined}

              {/* 指标列表 */}
              <el-select
                popper-class="derive-popper"
                onClick={(e: any) => {
                  setLoadMore(e.currentTarget);
                }}
                filterable
                remote={isRemote}
                v-model={currentIndex.value}
                remote-method={(content: string) => {
                  state.keyword = content;
                  state.pageNum = 1;
                  getArithmeticList();
                }}
                placeholder="请选择指标"
                onClear={() => {
                  state.keyword = "";
                  state.pageNum = 1;
                  getArithmeticList();
                }}
                onBlur={() => {
                  if (currentIndex.value == "") {
                    state.pageNum = 1;
                    getArithmeticList();
                  }
                }}
                clearable
                size="large"
              >
                {indexList?.value?.map((v: any, i: number) =>
                  isDetail ? (
                    <el-popover
                      popper-class="selectIndex_popper"
                      placement="left-start"
                      title={v?.cnName}
                      width="200"
                      trigger="hover"
                      v-slots={{
                        reference: () => (
                          <el-option
                            label={v?.label}
                            value={v.id}
                            onClick={() => {
                              state.currentItem = v;
                              splitData();
                            }}
                          ></el-option>
                        )
                      }}
                    >
                      <ArithmeticDetail list={formatDetail(v)} />
                    </el-popover>
                  ) : (
                    <el-option
                      key={v?.id}
                      label={v?.label}
                      value={v.id}
                      onClick={() => {
                        state.currentItem = v;
                      }}
                    ></el-option>
                  )
                )}
              </el-select>
            </div>
            {isSkip && (
              <el-button onClick={() => window.open(skipUrl)} type="text">
                + 新建指标
              </el-button>
            )}
          </div>
          {!isOnlyIndex && (<>
            <div class="SelectIndex-content">
              <div class="select-label">修饰词：</div>
              <div class="select-right">
                <ModifierCascader
                  list={modifierList.value}
                  v-model={[state.modifierIds, 'modelVal']}
                  onChange={(v: any[]) => {
                    //排序数组，时间修饰词在第一个，业务修饰词按照选择的顺序排列
                    let sortArray = [];
                    //找到时间修饰词，放入数组,在第一个位置添加
                    for (var i = v.length - 1; i >= 0; i--) {
                      if (v[i][0] == 1) {
                        sortArray.unshift(v[i]);
                        break;
                      }
                    }

                    let filterArray = v.filter(item => {
                      if (item[0] != 1) {
                        return item;
                      }
                    });
                    sortArray = sortArray.concat(filterArray);
                    //先清空在赋值
                    state.selectModifierList = [];
                    sortArray.map((modifier: any) => {
                      let parentNode = modifierList.value.find((obj: any) => obj.value == modifier[0]);
                      let childNode = parentNode.children.find((obj: any) => obj.value == modifier[1]);
                      state.selectModifierList.push(childNode);
                    });
                    state.modifierIds = sortArray;
                    //拼接数据
                    splitData();
                  }}
                ></ModifierCascader>
              </div>
            </div>
            <div class="SelectIndex-content">
              <div class="select-label is-not">组合名称：</div>
              <div class="select-right">
                <el-input
                  disabled={state.isDisableGroupName}
                  v-model={state.groupName}
                  style={{ width: '356px' }}
                  clearable
                  size="large"
                  placeholder="请输入组合名称"
                ></el-input>
                {state.isDisableGroupName && (
                  <el-button type="text" class="edit-btn" onClick={() => {
                    state.isDisableGroupName = false;
                  }}>编辑</el-button>
                )}
              </div>
            </div>
          </>)}

        </el-dialog>
      );
    };
  }
});
export default SelectIndex;
